#include <cstdlib>
#include <cstring>
#include <esp_err.h>
#include <esp_log.h>
#include <string>

#include "application.h"
#include "assets/lang_config.h"
#include "audio_codec.h"
#include "board.h"
#include "display.h"
#include "font_awesome_symbols.h"
#include "settings.h"

#define TAG "Display"

Display::Display() {
  // Load theme from settings
  Settings settings("display", false);
  current_theme_name_ = settings.GetString("theme", "light");

  // Notification timer
  esp_timer_create_args_t notification_timer_args = {
      .callback =
          [](void *arg) {
            Display         *display = static_cast<Display *>(arg);
            DisplayLockGuard lock(display);
            lv_obj_add_flag(display->notification_label_, LV_OBJ_FLAG_HIDDEN);
            lv_obj_clear_flag(display->status_label_, LV_OBJ_FLAG_HIDDEN);
          },
      .arg                   = this,
      .dispatch_method       = ESP_TIMER_TASK,
      .name                  = "notification_timer",
      .skip_unhandled_events = false,
  };
  ESP_ERROR_CHECK(esp_timer_create(&notification_timer_args, &notification_timer_));

  // Update display timer
  esp_timer_create_args_t update_display_timer_args = {
      .callback =
          [](void *arg) {
            Display *display = static_cast<Display *>(arg);
            display->Update();
          },
      .arg                   = this,
      .dispatch_method       = ESP_TIMER_TASK,
      .name                  = "display_update_timer",
      .skip_unhandled_events = true,
  };
  ESP_ERROR_CHECK(esp_timer_create(&update_display_timer_args, &update_timer_));
  ESP_ERROR_CHECK(esp_timer_start_periodic(update_timer_, 1000000));

  // Create a power management lock
  auto ret = esp_pm_lock_create(ESP_PM_APB_FREQ_MAX, 0, "display_update", &pm_lock_);
  if (ret == ESP_ERR_NOT_SUPPORTED) {
    ESP_LOGI(TAG, "Power management not supported");
  } else {
    ESP_ERROR_CHECK(ret);
  }
}

Display::~Display() {
  if (notification_timer_ != nullptr) {
    esp_timer_stop(notification_timer_);
    esp_timer_delete(notification_timer_);
  }
  if (update_timer_ != nullptr) {
    esp_timer_stop(update_timer_);
    esp_timer_delete(update_timer_);
  }

  if (network_label_ != nullptr) {
    lv_obj_del(network_label_);
    lv_obj_del(notification_label_);
    lv_obj_del(status_label_);
    lv_obj_del(mute_label_);
    lv_obj_del(battery_label_);
    lv_obj_del(emotion_label_);
  }

  if (pm_lock_ != nullptr) {
    esp_pm_lock_delete(pm_lock_);
  }
}

void Display::SetStatus(const char *status) {
  DisplayLockGuard lock(this);
  if (status_label_ == nullptr) {
    return;
  }
  lv_label_set_text(status_label_, status);
  lv_obj_clear_flag(status_label_, LV_OBJ_FLAG_HIDDEN);
  lv_obj_add_flag(notification_label_, LV_OBJ_FLAG_HIDDEN);
}

void Display::ShowNotification(const std::string &notification, int duration_ms) {
  ShowNotification(notification.c_str(), duration_ms);
}

void Display::ShowNotification(const char *notification, int duration_ms) {
  DisplayLockGuard lock(this);
  if (notification_label_ == nullptr) {
    return;
  }
  lv_label_set_text(notification_label_, notification);
  lv_obj_clear_flag(notification_label_, LV_OBJ_FLAG_HIDDEN);
  lv_obj_add_flag(status_label_, LV_OBJ_FLAG_HIDDEN);

  esp_timer_stop(notification_timer_);
  ESP_ERROR_CHECK(esp_timer_start_once(notification_timer_, duration_ms * 1000));
}

void Display::Update() {
  auto &board = Board::GetInstance();
  auto  codec = board.GetAudioCodec();

  {
    DisplayLockGuard lock(this);
    if (mute_label_ == nullptr) {
      return;
    }

    // 如果静音状态改变，则更新图标
    if (codec->output_volume() == 0 && !muted_) {
      muted_ = true;
      lv_label_set_text(mute_label_, FONT_AWESOME_VOLUME_MUTE);
    } else if (codec->output_volume() > 0 && muted_) {
      muted_ = false;
      lv_label_set_text(mute_label_, "");
    }
  }

  esp_pm_lock_acquire(pm_lock_);
  // 更新电池图标
  int         battery_level;
  bool        charging, discharging;
  const char *icon = nullptr;
  if (board.GetBatteryLevel(battery_level, charging, discharging)) {
    if (charging) {
      icon = FONT_AWESOME_BATTERY_CHARGING;
    } else {
      const char *levels[] = {
          FONT_AWESOME_BATTERY_EMPTY, // 0-19%
          FONT_AWESOME_BATTERY_1,     // 20-39%
          FONT_AWESOME_BATTERY_2,     // 40-59%
          FONT_AWESOME_BATTERY_3,     // 60-79%
          FONT_AWESOME_BATTERY_FULL,  // 80-99%
          FONT_AWESOME_BATTERY_FULL,  // 100%
      };
      icon = levels[battery_level / 20];
    }
    DisplayLockGuard lock(this);
    if (battery_label_ != nullptr && battery_icon_ != icon) {
      battery_icon_ = icon;
      lv_label_set_text(battery_label_, battery_icon_);
    }

    if (low_battery_popup_ != nullptr) {
      if (strcmp(icon, FONT_AWESOME_BATTERY_EMPTY) == 0 && discharging) {
        if (lv_obj_has_flag(low_battery_popup_, LV_OBJ_FLAG_HIDDEN)) { // 如果低电量提示框隐藏，则显示
          lv_obj_clear_flag(low_battery_popup_, LV_OBJ_FLAG_HIDDEN);
          auto &app = Application::GetInstance();
          app.PlaySound(Lang::Sounds::P3_LOW_BATTERY);
        }
      } else {
        // Hide the low battery popup when the battery is not empty
        if (!lv_obj_has_flag(low_battery_popup_, LV_OBJ_FLAG_HIDDEN)) { // 如果低电量提示框显示，则隐藏
          lv_obj_add_flag(low_battery_popup_, LV_OBJ_FLAG_HIDDEN);
        }
      }
    }
  }

  // 升级固件时，不读取 4G 网络状态，避免占用 UART 资源
  auto                                  device_state   = Application::GetInstance().GetDeviceState();
  static const std::vector<DeviceState> allowed_states = {
      kDeviceStateIdle,
      kDeviceStateStarting,
      kDeviceStateWifiConfiguring,
      kDeviceStateListening,
  };
  if (std::find(allowed_states.begin(), allowed_states.end(), device_state) != allowed_states.end()) {
    icon = board.GetNetworkStateIcon();
    if (network_label_ != nullptr && icon != nullptr && network_icon_ != icon) {
      DisplayLockGuard lock(this);
      network_icon_ = icon;
      lv_label_set_text(network_label_, network_icon_);
    }
  }

  esp_pm_lock_release(pm_lock_);
}

void Display::SetEmotion(const char *emotion) {
  struct Emotion {
    const char *icon;
    const char *text;
  };

  static const std::vector<Emotion> emotions = {
      {FONT_AWESOME_EMOJI_NEUTRAL, "neutral"},
      {FONT_AWESOME_EMOJI_HAPPY, "happy"},
      {FONT_AWESOME_EMOJI_LAUGHING, "laughing"},
      {FONT_AWESOME_EMOJI_FUNNY, "funny"},
      {FONT_AWESOME_EMOJI_SAD, "sad"},
      {FONT_AWESOME_EMOJI_ANGRY, "angry"},
      {FONT_AWESOME_EMOJI_CRYING, "crying"},
      {FONT_AWESOME_EMOJI_LOVING, "loving"},
      {FONT_AWESOME_EMOJI_EMBARRASSED, "embarrassed"},
      {FONT_AWESOME_EMOJI_SURPRISED, "surprised"},
      {FONT_AWESOME_EMOJI_SHOCKED, "shocked"},
      {FONT_AWESOME_EMOJI_THINKING, "thinking"},
      {FONT_AWESOME_EMOJI_WINKING, "winking"},
      {FONT_AWESOME_EMOJI_COOL, "cool"},
      {FONT_AWESOME_EMOJI_RELAXED, "relaxed"},
      {FONT_AWESOME_EMOJI_DELICIOUS, "delicious"},
      {FONT_AWESOME_EMOJI_KISSY, "kissy"},
      {FONT_AWESOME_EMOJI_CONFIDENT, "confident"},
      {FONT_AWESOME_EMOJI_SLEEPY, "sleepy"},
      {FONT_AWESOME_EMOJI_SILLY, "silly"},
      {FONT_AWESOME_EMOJI_CONFUSED, "confused"}};

  // 查找匹配的表情
  std::string_view emotion_view(emotion);
  auto             it = std::find_if(
      emotions.begin(), emotions.end(), [&emotion_view](const Emotion &e) { return e.text == emotion_view; });

  DisplayLockGuard lock(this);
  if (emotion_label_ == nullptr) {
    return;
  }

  // 如果找到匹配的表情就显示对应图标，否则显示默认的neutral表情
  if (it != emotions.end()) {
    lv_label_set_text(emotion_label_, it->icon);
  } else {
    lv_label_set_text(emotion_label_, FONT_AWESOME_EMOJI_NEUTRAL);
  }
}

void Display::SetIcon(const char *icon) {
  DisplayLockGuard lock(this);
  if (emotion_label_ == nullptr) {
    return;
  }
  lv_label_set_text(emotion_label_, icon);
}

void Display::SetChatMessage(const char *role, const char *content) {
  DisplayLockGuard lock(this);
  if (chat_message_label_ == nullptr) {
    return;
  }
  lv_label_set_text(chat_message_label_, content);
}

void Display::SetTheme(const std::string &theme_name) {
  current_theme_name_ = theme_name;
  Settings settings("display", true);
  settings.SetString("theme", theme_name);
}

void Display::SetChatMessageTest(const char *role, const char *content) {
  DisplayLockGuard lock(this); // 确保线程安全

  // 如果 label 还没创建，就创建它
  if (chat_message_label_ == nullptr) {
    lv_obj_t *parent    = lv_scr_act(); // 当前活动屏幕
    chat_message_label_ = lv_label_create(parent);
    lv_label_set_long_mode(chat_message_label_, LV_LABEL_LONG_WRAP); // 自动换行
    lv_obj_set_width(chat_message_label_, lv_pct(80));               // 宽度设为屏幕 80%
    lv_obj_align(chat_message_label_, LV_ALIGN_CENTER, 0, 0);        // 居中显示
    ESP_LOGD(TAG,"chat_message_label_ created");
  }

  lv_label_set_text(chat_message_label_, content);        // 更新文本
  lv_obj_scroll_to_view(chat_message_label_, LV_ANIM_ON); // 滚动可见（可选）

  ESP_LOGD(TAG,"SetChatMessageTest");

}
